package com.leaf.spring.y201906.day25.arithmetic.round;

import java.util.ArrayList;
import java.util.Set;

import com.leaf.spring.y201906.day25.arithmetic.ServerIps;

/**
 * 轮询 + 权重
 * 
 * @Title:
 * @Description:
 * @Author: leaf
 * @Since:2019年6月25日
 * @Version:1.1.0
 */
public class WeightRoundRobinArith {

	private static Integer pos = 0;

	public String getServer() {

		int totalWeight = 0; // 总权重值
		boolean sameWeight = true; // 如果所有权重值都相等，则随机一个服务就可以了

		Object[] weights = ServerIps.WEIGHT_LIST.values().toArray();

		for (int i = 0; i < weights.length; i++) {

			Integer weight = (Integer) weights[i];
			totalWeight += weight;

			if (sameWeight && i > 0 && !weight.equals(weights[i - 1])) {
				sameWeight = false;
			}
		}

		// 取模
		Integer sequenceNum = Sequence.getAndIncrement();
		Integer offset = sequenceNum % totalWeight;
		
		// 权重值不相等
		if (!sameWeight) {

			for (String server : ServerIps.WEIGHT_LIST.keySet()) {

				int weight = ServerIps.WEIGHT_LIST.get(server);

				// 将当前key的权重weight与pos比较，
				// 若weight大于pos，则说明pos在当前weight内
				// 若weight小于pos，则将pos移动weight位
				if (weight > offset) {
					return server;
				}
				offset = offset - weight;

			}
		}

		String server = null;

		// 轮询
		synchronized (pos) {

			Set<String> servers = ServerIps.WEIGHT_LIST.keySet();

			if (pos >= servers.size()) {
				pos = 0;
			}

			server = new ArrayList<String>(servers).get(pos);

			pos++;
		}

		return server;

	}

	public static void main(String[] args) {

		for (int i = 0; i < 30; i++) {
			System.out.println(new WeightRoundRobinArith().getServer());
		}

	}

}
